import { fabric } from 'fabric';
import { checkCensorImage, humanSegment, getAliyunCosSignature } from '@/utils/api';
import { diyCustomControlRender, userCustomControlRender } from './initEvent';
import { Toast } from 'vant';
import Axios from 'axios';
import store from '../../store';
import config from '@/utils/config';
let handAccountCanvas = null; // 手账画布对象
let ratioNum = 1; // 画布的width,height比列 1.567745
let canvasContentEl = null // 画布容器
let previous = []; // 历史队列
let future = []; // 未来队列
let viewWc = 1;
let loadRectFalg = false;
let toJsonAttr = [ 'isEdit', 'elType', 'isMove', 'isMatting', 'fontFamilySrc', 'selectable', '_index', 'crossOrigin', 'evented', 'colorType', 'opacity', 'xieYinColor', 'xieYinText', 'lockMovementX', 'lockMovementY', 'isSticker', 'textDirection', 'isXieyinImage' ];
let cosConfig = null;

// 测试计算点
let startPoint = null;
let currentPoint = null;
let endPoint = [];

// 获取aliyun oss sign
function getAliyunCosSignatureFn() {
  // cos上传签名
  getAliyunCosSignature().then(result => {
    if (result && result.data) {
      cosConfig = result.data;
    }
  });
}

/**
 * 获取画布尺寸
 * @returns Object width height
 */
async function getCurrentCanvasHeight(CW, CH) {
  let size = {
    width: CW,
    height: CH
  }
  console.log(size)
  while((canvasContentEl.offsetHeight - 16) < CH) {
    CW -= 16;
    CH = CW * ratioNum;
    size = {
      width: CW,
      height: CH
    }
  }
  console.log(size)
  return size
}

/**
 * 初始化画布
 * design_type 画布类型
 * selection 是否可以自由选择成组
 */
 async function initCanvas(design_type, selection) {

  // 画布滚动事件重写
  (function(){
    var defaultOnTouchStartHandler = fabric.Canvas.prototype._onTouchStart;
    fabric.util.object.extend(fabric.Canvas.prototype, { 
      _onTouchStart: function(e) { 
        var target = this.findTarget(e);
        // 点击时没有选择中画布的原素
        if (this.allowTouchScrolling && !target && !this.isDrawingMode) {
          handAccountCanvas.discardActiveObject();
          handAccountCanvas.renderAll();
          return;
        }
        defaultOnTouchStartHandler.call(this, e);
      } 
    });
  })();

  canvasContentEl = document.querySelector(`#canvasContentEl`); // 画布容器
  // let CW = window.innerWidth - 24; // 画布初始宽度
  // let CH = CW * ratioNum;
  // const canvasSize = await getCurrentCanvasHeight(CW, CH); // 获取画布尺寸

  const width = canvasContentEl.offsetWidth; 
  const height = canvasContentEl.offsetHeight;

  // 初始化画布
  handAccountCanvas = new fabric.Canvas('canvas', {
    isDrawingMode: false, // 开启绘画模式
    width, // 画布宽度
    height, // 画布高度
    backgroundColor: '#000', // 画布背景色
    selection: selection || false, // 是否可以选择
    allowTouchScrolling: false, // 指示在使用触摸屏并在画布上拖动时是否可以滚动浏览器
    enableRetinaScaling: true, // 设置为true时，devicePixelRatio缩放画布以在视网膜屏幕上更好地渲染
    controlsAboveOverlay: true, // 超出clipPath后仍然展示控制条
    preserveObjectStacking: true // 当设置为true的时候是在当前层,设置为false时是置顶选中元素,默认的是false的情况
  })

  // 自定义控件呈现
  if (design_type == 1) {
    diyCustomControlRender();
  } else if (design_type == 2) {
    userCustomControlRender();
  }

  // 监听选中事件
  handAccountCanvas.on('selection:created', () => {
    // 当前选中原素的操作
    const currentObject = handAccountCanvas.getActiveObject();
    // 删除默认控件
    currentObject['setControlVisible']('ml', false) // 中左
    currentObject['setControlVisible']('mb', false) // 中下
    currentObject['setControlVisible']('mr', false) // 中右
    currentObject['setControlVisible']('mt', false) // 中上
    currentObject['setControlVisible']('tl', false) // 左上角
    currentObject['setControlVisible']('tr', false) // 上右角
    currentObject['setControlVisible']('bl', false) // 左上角

    store.dispatch('design/setCurrentSelectionElement', currentObject);
    // 图片类型
    if (currentObject && currentObject.type === 'image') {
      store.dispatch('design/setCurrentSelectionType', 'sliderOpacity');
    } else if (currentObject && currentObject.type === 'textbox') {
      store.dispatch('design/setCurrentSelectionType', 'text');
    } else if (currentObject && currentObject.type === 'group') {
      
    }
  });

  // 监听取消选择事件
  handAccountCanvas.on('selection:cleared', () => {
    store.dispatch('design/setCurrentSelectionElement', '');
    store.dispatch('design/setCurrentSelectionType', '');
  });

  // 监听更新选择事件
  handAccountCanvas.on('selection:updated', () => {
    // 当前选中原素的操作
    const currentObject = handAccountCanvas.getActiveObject();
    // 删除默认控件
    currentObject['setControlVisible']('ml', false) // 中左
    currentObject['setControlVisible']('mb', false) // 中下
    currentObject['setControlVisible']('mr', false) // 中右
    currentObject['setControlVisible']('mt', false) // 中上
    currentObject['setControlVisible']('tl', false) // 左上角
    currentObject['setControlVisible']('tr', false) // 上右角
    currentObject['setControlVisible']('bl', false) // 左上角

    store.dispatch('design/setCurrentSelectionElement', currentObject);
    // 图片类型
    if (currentObject && currentObject.type === 'image') {
      store.dispatch('design/setCurrentSelectionType', 'sliderOpacity');
    } else if (currentObject && currentObject.type === 'textbox') {
      store.dispatch('design/setCurrentSelectionType', 'text');
    }
  });

  // 监听路径
  handAccountCanvas.on('before:path:created', function(opt) {
    var path = opt.path;
    var pathInfo = fabric.util.getPathSegmentsInfo(path.path);
    path.segmentsInfo = pathInfo;
  });

  // 清除path
  handAccountCanvas.on('path:created', function(opt) {
    handAccountCanvas.isDrawingMode = false;
    handAccountCanvas.renderAll();
  });

  // 鼠标按下
  handAccountCanvas.on('mouse:down', (options) => {
    startPoint = options.pointer;
    endPoint.push(startPoint);
  });

  // 移动
  handAccountCanvas.on('mouse:move', async (options) => {
    currentPoint = options.pointer;
    if (startPoint) {
      let dep = Math.sqrt(Math.pow((startPoint.x - currentPoint.x), 2) + Math.pow((startPoint.y - currentPoint.y), 2));
      dep = parseInt(dep);
      endPoint.push(currentPoint);
      if (dep > 10 && dep < 12) {
        startPoint = currentPoint;
      }
      const currentObject = handAccountCanvas.getActiveObject();
      store.dispatch('design/setCurrentSelectionElement', currentObject);
    }
  });

  // 弹起
  handAccountCanvas.on('mouse:up', (options) => {
    const activeObj = handAccountCanvas.getActiveObject();
    if (activeObj) {
      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
    }
    endPoint.push(options.pointer);
  });

  // 双指手势取消移动
  handAccountCanvas.on("touch:gesture", () => {
    // getActiveObject 返回当前活动对象
    const activeObj = handAccountCanvas.getActiveObject();
    if (activeObj) {
      activeObj.set({
        lockMovementX: true,
        lockMovementY: true,
      });
    }
  });
}

// 计算出两点的距离
// 两点的距离
async function getDistance(p1, p2){
  let dep = Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2));
  return dep;
}

/**
 * 设置背景
 * type color纯色 img图片背景
 * uri 图片链接
 * color 色值编码
 */
function setCanvasBackground({ type, color, uri, isLoad = false }) {
  return new Promise((resolve, reject) => {
    if (type === 'color') {
      handAccountCanvas.backgroundColor = color;
      handAccountCanvas.renderAll();
      resolve();
  
      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      // const canvasJson = handAccountCanvas.toJSON();
      // previous.push(JSON.stringify(canvasJson));
    } else {

      if (!isLoad) {
        handAccountCanvas.clear();
      }

      fabric.Image.fromURL(uri, async (img) => {
        // 设置上传背景，并重置画布大小
        ratioNum = img.height / img.width;
        const currentImgWidth = window.innerWidth - 24;
        const currentImgHeight = (currentImgWidth / img.width) * img.height;
        const canvasSize = await getCurrentCanvasHeight(currentImgWidth, currentImgHeight); // 获取画布尺寸
        handAccountCanvas.setDimensions({
          width: canvasSize.width,
          height: canvasSize.height
        })
        handAccountCanvas.setBackgroundImage(img, handAccountCanvas.renderAll.bind(handAccountCanvas), {
          scaleX: handAccountCanvas.width / img.width,
          scaleY: handAccountCanvas.height / img.height
        });

        // 是否加载过画布
        if (!isLoad) {
          setSysZoomAuto(viewWc, canvasSize.width, canvasSize.height);
        }

        // store.dispatch('design/setShowAddBackgroundImage', true);

        resolve({
          width: canvasSize.width,
          height: canvasSize.height
        });
        
        // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
        // const canvasJson = handAccountCanvas.toJSON();
        // previous.push(JSON.stringify(canvasJson));
      }, { crossOrigin: 'anonymous' });
    }
  })
}

// 获取autoSize 
function getCanvasSize({ uri }) {
  return new Promise((resolve, reject) => {
    fabric.Image.fromURL(uri, async (img) => {
      // 设置上传背景，并重置画布大小
      ratioNum = img.height / img.width;
      const currentImgWidth = window.innerWidth - 24;
      const currentImgHeight = (currentImgWidth / img.width) * img.height;
      const canvasSize = await getCurrentCanvasHeight(currentImgWidth, currentImgHeight); // 获取画布尺寸
      resolve({
        width: canvasSize.width,
        height: canvasSize.height
      });
      
      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      // const canvasJson = handAccountCanvas.toJSON();
      // previous.push(JSON.stringify(canvasJson));
    }, { crossOrigin: 'anonymous' });
  })
}

/**
 * 添加图片
 * options: 配置参数等 id之类
 * uri: 图片链接
 */
function addImage({ options = {}, uri }) {
  return new Promise((resolve, reject) => {
    // let url = 'https://res.guxitk.com/2023/08/26/20230826205251-IMG_8537.png';
    new fabric.Image.fromURL(uri, (img) => {
      img.set(Object.assign(options, {
        selection: false,
        fill: '#fff',
        opacity: 1,
        padding: 0,
        borderScaleFactor: 1.5,
        crossOrigin: 'anonymous',
        isEdit: true,
        isMove: false,
        isMatting: false,
        selectable: true,
        isSticker: false,
        isXieyinImage: false
        // stroke: "#ffffff", 
        // strokeWidth: 30
      }));
      // 如果图片的宽度大于200，则缩放到100
      if (img.width > 200) {
        img.scaleToWidth(100);
      }
      handAccountCanvas.add(img);
      handAccountCanvas.viewportCenterObject(img); // 垂直水平居中
      handAccountCanvas.setActiveObject(img);
      // 图片描边
      // let image = strokeImage(uri);

      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
      resolve();
    }, {crossOrigin: 'anonymous'});
  })
}

/**
 * 添加图片
 * options: 配置参数等 id之类
 * uri: 图片链接
 */
function addCarModelImage({ options = {}, uri }) {
  return new Promise(async (resolve, reject) => {
    const currentImgWidth = window.innerWidth - 24;
    // let url = 'https://res.guxitk.com/2023/08/26/20230826205251-IMG_8537.png';
    new fabric.Image.fromURL(uri, (img) => {
      img.set(Object.assign(options, {
        selection: false,
        fill: '#fff',
        opacity: 1,
        padding: 0,
        borderScaleFactor: 1.5,
        crossOrigin: 'anonymous',
        isEdit: true,
        isMove: false,
        isMatting: false,
        selectable: true,
        isSticker: false,
        isXieyinImage: false,
        lockMovementX: true,
        lockMovementY: true,
        // stroke: "#ffffff", 
        // strokeWidth: 30
      }));
      // 如果图片的宽度大于200，则缩放到100
      img.scaleToWidth(currentImgWidth);
      handAccountCanvas.add(img);
      handAccountCanvas.viewportCenterObject(img); // 垂直水平居中
      // handAccountCanvas.setActiveObject(img);
      // 图片描边
      // let image = strokeImage(uri);

      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
      resolve();
    }, {crossOrigin: 'anonymous'});
  })
}

/**
 * 图片描边
 * @param {string} url - 图片地址或base64
 * @param {string} [borderColor=red] - 描边颜色
 * @param {number} [borderWidth=4] - 描边宽度
 * @return {string} base64 - 描边后的图片字符串
 */
function strokeImage(url, borderColor='red', borderWidth = 4) {
  return new Promise((resolve) => {
    // create canvas
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");

    // create image
    const image = new Image();
    image.onload = draw;
    image.src = url;
    image.crossOrigin = "Anonymous";

    function draw() {
      canvas.width = image.width + 50;
      canvas.height = image.height + 50;

      const dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1]; // offset array

      // 平移图像
      for (let i = 0; i < dArr.length; i += 2)
        ctx.drawImage(image, dArr[i] * borderWidth, dArr[i + 1] * borderWidth);

      // 填充描边色
      ctx.globalCompositeOperation = "source-in";
      ctx.fillStyle = borderColor;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // 添加原图
      ctx.globalCompositeOperation = "source-over";
      ctx.drawImage(image, 0, 0);

      resolve(canvas.toDataURL());
    }
  });
}


/**
 * 更新图片
 * @param {*} type 类型
 * @param {*} uri 图片链接
 * 
 */
function updatedImageItem({ type, uri }) {
  return new Promise((resolve, reject) => {
    let activeSelection = handAccountCanvas.getActiveObject();
    if (type === 'src') {
      activeSelection.setSrc(uri, img => {
        activeSelection.set('screenX', 1);
        activeSelection.set('screenY', 1);
        activeSelection.set('crossOrigin', 'anonymous');
        if (img.width > 200) {
          img.scaleToWidth(150);
        }
        handAccountCanvas.renderAll();

        // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
        if (img.width <= 200) {
          const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
          previous.push(JSON.stringify(canvasJson));
        }

        resolve({
          width: img.width
        });
      }, {crossOrigin: 'anonymous'});
    } else if (type === 'width') {
      activeSelection.set('screenX', 1);
      activeSelection.set('screenY', 1);
      activeSelection.scaleToWidth(150);
      handAccountCanvas.renderAll();

      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
      resolve();
    }
  })
}

/**
 * 汽车头像更换挂件
 * @param {*} type 类型
 * @param {*} uri 图片链接
 * 
 */
function changeCarSticker({ uri }) {
  return new Promise((resolve, reject) => {
    let activeSelection = handAccountCanvas.getObjects().filter(item => item.elType === 'paster')[0];
    activeSelection.setSrc(uri, img => {
      activeSelection.set('crossOrigin', 'anonymous');
      // handAccountCanvas.renderAll();

      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
      handAccountCanvas.setActiveObject(activeSelection);
      handAccountCanvas.renderAll();
      store.dispatch('design/setItemList', canvasJson.objects);
      resolve();
    }, {crossOrigin: 'anonymous'});
  })
}

/**
 * 更换贴纸
 * @param {*} type 类型
 * @param {*} uri 图片链接
 * 
 */
function changeSticker({ uri }) {
  return new Promise((resolve, reject) => {
    let activeSelection = handAccountCanvas.getObjects().filter(item => item.isSticker)[0];
    activeSelection.setSrc(uri, img => {
      activeSelection.set('crossOrigin', 'anonymous');
      // handAccountCanvas.renderAll();

      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
      handAccountCanvas.setActiveObject(activeSelection);
      handAccountCanvas.renderAll();
      resolve();
    }, {crossOrigin: 'anonymous'});
  })
}

// 设置底图
function setBackgroundImage() {
  return new Promise((resolve, reject) => {
    let handAccountCanvasJson = handAccountCanvas.toJSON(toJsonAttr);
    let backgroundImage = handAccountCanvasJson.backgroundImage;
    let clipPath = handAccountCanvasJson.clipPath;
    let currentObject = handAccountCanvas.getActiveObject();
    currentObject.set('left', 0);
    currentObject.set('top', 0);
    currentObject.set('width', backgroundImage.width);
    currentObject.set('height', backgroundImage.height);
    currentObject.set('scaleX', clipPath.width / backgroundImage.width);
    currentObject.set('scaleY', clipPath.height / backgroundImage.height);
    handAccountCanvas.renderAll();
  })
}

// 取消选中的原素
function discardActiveObject() {
  return new Promise((resolve, reject) => {
    handAccountCanvas.discardActiveObject();
    handAccountCanvas.renderAll();
    resolve();
  })
}

// 设置选中元素的透明度
function setActiveObjectOpacity(number, type) {
  return new Promise((resolve, reject) => {
    let activeSelection = handAccountCanvas.getActiveObject();
    activeSelection.set('opacity', number / 100);

    // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
    if (type === 'drag-end') {
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
    }

    handAccountCanvas.renderAll();

    resolve();
  })
}

/**
 * 添加文本
 * content 文本信息
 * type text
 * fontSize 字体大小默认16
 */
function addText({ content = '', type = 'text', fontSize = '20', elType,fill }) {
  console.log('add',content,elType)
  return new Promise((resolve, reject) => {
    let text = new fabric.Textbox(content, {
      colorType: 'color',
      fill:fill,
      strokeWidth: 0,
	    stroke: "#000000",
      fontSize,
      splitByGrapheme: true,
      editable: false,
      padding: 0,
      width: 70,
      textAlign: 'center',
      shadow: null,
      fontWeight: 'normal',
      borderScaleFactor: 1.5,
      lineHeight: 1.0,
      charSpacing: 0,
      isEdit: true,
      isMove: false,
      selectable: true,
      fontFamilySrc: '',
      elType
    })
    handAccountCanvas.add(text);
    handAccountCanvas.viewportCenterObject(text); // 垂直水平居中
    handAccountCanvas.setActiveObject(text);
    handAccountCanvas.renderAll();

    // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
    const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
    previous.push(JSON.stringify(canvasJson));

    resolve();
  })
}

/**
 * 更改文本框信息
 * @param {*} type 类型 text更改文本信息 decreaseFontSize减小字体大小 increaseFontSize增加字体大小 fontFamily设置字体
 * textAlign对齐方式 shadow阴影 fontWeight字体是否加粗 lineHeight行高 charSpacing字距
 * @param {*} content 内容
 * @returns object
 */
function updateTextBox({ type, content, src, sliderType }) {
  return new Promise((resolve, reject) => {
    let activeSelection = handAccountCanvas.getActiveObject();
    if (!activeSelection) {
      return;
    }
    if (type === 'text') {
      activeSelection.set('text', content);
    } else if (type === 'decreaseFontSize' || type === 'increaseFontSize') {
      activeSelection.set('fontSize', content);

      // 渐变颜色改变高度
      if (activeSelection.colorType === 'gradient') {
        let gradient = new fabric.Gradient({
          type: "linear",
          coords: {
            x1: 0,
            y1: 0,
            x2: 0,
            y2: activeSelection.height
          },
          colorStops: [
            {
              offset: 0,
              color: activeSelection.fill.colorStops[0].color
            },
            {
              offset: 0.7220805921052632,
              color: activeSelection.fill.colorStops[1].color
            },
            {
              offset: 1,
              color: activeSelection.fill.colorStops[1].color
            }
          ],
          offsetX: 0,
          offsetY: 0,
          gradientUnits: "pixels",
          gradientTransform: null
        });
        activeSelection.set('fill', gradient);
      }
    } else if (type === 'fontFamily') {
      activeSelection.set('fontFamily', content);
      activeSelection.set('fontFamilySrc', src);
    } else if (type === 'color') {
      activeSelection.set('fill', content);
      activeSelection.set('colorType', 'color');
    } else if (type === 'gradient') {
      let gradient = new fabric.Gradient({
        type: "linear",
        coords: {
          x1: 0,
          y1: 0,
          x2: 0,
          y2: activeSelection.height
        },
        colorStops: [
          {
            offset: 0,
            color: content.fill_color1
          },
          {
            offset: 0.7220805921052632,
            color: content.fill_color2
          },
          {
            offset: 1,
            color: content.fill_color2
          }
        ],
        offsetX: 0,
        offsetY: 0,
        gradientUnits: "pixels",
        gradientTransform: null
      });
      activeSelection.set('fill', gradient);
      activeSelection.set('colorType', 'gradient');
    } else if (type === 'textAlign') {
      activeSelection.set('textAlign', content);
    } else if (type === 'shadow') {
      activeSelection.set('shadow', content);
    } else if (type === 'fontWeight') {
      activeSelection.set('fontWeight', content);
    } else if (type === 'lineHeight') {
      activeSelection.set('lineHeight', parseFloat(content).toFixed(1));
    } else if (type === 'charSpacing') {
      activeSelection.set('charSpacing', content);
    } else if (type === 'strokeWidth') {
      activeSelection.set('strokeWidth', content);
    } else if (type === 'stroke') {
      activeSelection.set('stroke', content);
    } else if (type === 'xieYin') {
      let text = activeSelection.text.split('');
      let xieYinColor = content.xieYinColor;
      let xieYinText = content.xieYinText;
      let textDirection = content.textDirection;
      let index = text.findIndex(item => item === xieYinText);
      activeSelection.set('xieYinColor', xieYinColor);
      activeSelection.set('xieYinText', xieYinText);
      activeSelection.set('textDirection', textDirection);
      activeSelection.set('styles', { 0: { [index]: { fill: xieYinColor } }});
    }
    handAccountCanvas.renderAll();
    if (type !== 'strokeWidth') {
      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
    }

    if (sliderType === 'drag-end') {
      // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
      const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
      previous.push(JSON.stringify(canvasJson));
    }

    resolve();
  })
}

// 添加组
function addGroup() {
  return new Promise(async (resolve, reject) => {
    handAccountCanvas.getActiveObject().toGroup();
    handAccountCanvas.discardActiveObject();
    handAccountCanvas.renderAll();
    resolve();
  })
}

// 添加汽车车系模型
async function addCarModel(carModel) {
  return new Promise(async (resolve, reject) => {
    let carText= localStorage.getItem('carText');
    let groupItem = handAccountCanvas.getObjects().filter(item => item.type === 'group')[0];
    if (carModel && carModel[0].objects) {
      for (const objects of carModel[0].objects) {
        if (objects.fontFamilySrc && objects.fontFamily) {
          await downLoadFont({
            name: objects.fontFamily,
            url: objects.fontFamilySrc
          });

          if (objects.elType === 'car-model-text' && carText) {
            objects.text = carText;
          }

        }
      }
    };

    if (groupItem) {
      let left = groupItem.left;
      let top = groupItem.top;
      let scaleY = groupItem.scaleY;
      let scaleX = groupItem.scaleX;
      let _index = groupItem._index;
      carModel[0].left = left;
      carModel[0].top = top;
      carModel[0].scaleY = scaleY;
      carModel[0].scaleX = scaleX;
      carModel[0]._index = _index;
      fabric.util.enlivenObjects(carModel, function(objects) {
        handAccountCanvas.remove(groupItem); // 先移除group
        handAccountCanvas.add(...objects); // 在添加group
        handAccountCanvas.setActiveObject(...objects);
        handAccountCanvas.renderAll();
        let activeSelection = handAccountCanvas.getActiveObject();
        activeSelection.moveTo(_index); // 移动到所在的层次
      });

    } else {
      fabric.util.enlivenObjects(carModel, function(objects) {
        handAccountCanvas.add(...objects);
        handAccountCanvas.setActiveObject(...objects);
        handAccountCanvas.renderAll();
      });
    }
  });
}

// 更换车牌
function changeCarText(text) {
  return new Promise(async (resolve, reject) => {
    let group = handAccountCanvas.getObjects().filter(item => item.type === 'group')[0];
    group.forEachObject(function(obj) {
      if (obj.type === 'textbox') {
        obj.set('text', text);
      }
    });
    // 因为文本改变了，需要重新渲染画布
    handAccountCanvas.renderAll();
    resolve();
  });
}

// 更换姓氏谐音文字
function changeSurnameXieYie({ type, content, src, sliderType }) {
  return new Promise((resolve, reject) => {
    // 文字颜色变化
    let text = content.text;
    let textArray = text.split('');
    let xieYinText = content.xieYinText;
    let textIndex = textArray.findIndex(item => item === xieYinText);
    let xieyinIndex = content.xieyinIndex;
    let textObjects = handAccountCanvas.getObjects().filter(item => item.type === 'textbox' && item.xieYinText && item.textDirection);
    const changeCurrentObjects = textObjects[xieyinIndex];
    let xieYinColor = changeCurrentObjects.xieYinColor;
    let textDirection = changeCurrentObjects.textDirection;
    changeCurrentObjects.set('text', text);
    changeCurrentObjects.set('xieYinText', xieYinText);
    changeCurrentObjects.set('styles', { 0: { [textIndex]: { fill: xieYinColor } }});

    // 谐音底图
    let imageObjects = handAccountCanvas.getObjects().filter(item => item.type === 'image' && item.isXieyinImage);
    // 文字横向设置
    if (textDirection === 'horizontal') {
      let imageLeft = changeCurrentObjects.left + ((changeCurrentObjects.width * changeCurrentObjects.scaleX) / text.length) * textIndex;
      imageObjects[xieyinIndex].set('left', imageLeft - 5);
    } else if (textDirection === 'vertical') {
      let imageTop = changeCurrentObjects.top + ((changeCurrentObjects.height * changeCurrentObjects.scaleY) / text.length) * textIndex;
      imageObjects[xieyinIndex].set('top', imageTop - 5);
    }
    imageObjects[xieyinIndex].set('selectable', true);

    handAccountCanvas.setActiveObject(imageObjects[xieyinIndex]);
    // 更新姓氏
    let params = handAccountCanvas.getObjects();
    params.forEach((item, index) => {
      item._index = index;
    });
    store.dispatch('design/setItemList', params);
    handAccountCanvas.renderAll();
    resolve();
  })
}

/**
 * 更新元素属性
 * type 元素类型
 * flag 开关
 */
function updatedItem(type, flag) {
  return new Promise((resolve, reject) => {
    let activeSelection = handAccountCanvas.getActiveObject();
    if (type === 'edit') {
      activeSelection.set('isEdit', flag);
    } else if (type === 'move') {
      activeSelection.set('lockMovementX', flag);
      activeSelection.set('lockMovementY', flag);
      activeSelection.set('isMove', flag);
    } else if (type === 'selectable') {
      activeSelection.set('selectable', flag);
      activeSelection.set('evented', flag);
      
      // 取消选中
      if (!flag) {
        Toast({
          message: '图层已锁定，用户不能编辑和移动，如需编辑、删除请解除锁定',
          position: 'center'
        });
        handAccountCanvas.discardActiveObject();
      }
    } else if (type === 'matting') {
      activeSelection.set('isMatting', flag);
    } else if (type === 'sticker') {
      activeSelection.set('isSticker', flag);
    } else if (type === 'xieyinImage') {
      activeSelection.set('isXieyinImage', flag);
    }

    handAccountCanvas.renderAll();
    // 每次 增删改 操作，都会将当前画布序列化，并压入 previous
    const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
    previous.push(JSON.stringify(canvasJson));

    resolve();
  })
}

/**
 * 下载字体
 * name字体名称
 * url字体链接
 */
function downLoadFont({ name, url }) {
  return new Promise((resolve, reject) => {
    if (store.state.design.fontList[name]) {
      resolve(name);
    } else {
      Toast.loading({
        message: '加载中',
        position: 'center',
        forbidClick: true,
        duration: 0
      });
      let fontFace = new FontFace(name, `url(${url})`);
      fontFace.load().then(loadedFontFace => {
        document.fonts.add(loadedFontFace);
        store.dispatch('design/setFontList', name);
        Toast.clear();
        resolve(loadedFontFace);
      }).catch(() => {
        reject();
      });
    }
  })
}

/**
 * 获取对象
 */
function getObject() {
  return handAccountCanvas;
}

/**
 * 获取对象
 */
function getObjects() {
  return handAccountCanvas.getObjects();
}

// 获取缩放比例
function getViewWc() {
  return viewWc;
}

/**
 * 置底
 */
function itemSendToBack() {
  const currentObject = handAccountCanvas.getActiveObject();
  currentObject.sendToBack();
}

/**
 * 下一层
 */
function itemSendBackwards() {
  const currentObject = handAccountCanvas.getActiveObject();
  currentObject.sendBackwards();
}

/**
 * 置顶
 */
function itemBringToFront() {
  const currentObject = handAccountCanvas.getActiveObject();
  currentObject.bringToFront();
}

/**
 * 上一层
 */
function itemBringForward() {
  const currentObject = handAccountCanvas.getActiveObject();
  currentObject.bringForward();
}

/**
 * 上一步
 */
function prevStepOperate() {
  return new Promise((resolve) => {
    let design_type = store.state.user.queryParams.design_type;
    let prev = [ ...previous ], fut = [ ...future ];
    if (prev.length === 1) {
      // prev 只剩最后一值，已到最前
      return Toast({
        message: '已是最后一步',
        position: 'center'
      });
    }

    // prev 出栈，压入 fut
    fut.push(prev.pop());
    // 设置 prev 最后一值为当前画布内容
    handAccountCanvas.clear();
    let handAccountObject = prev[prev.length - 1];
    let handAccountJson = JSON.parse(handAccountObject);
    let objectsList = handAccountJson.objects;
    for (const objects of objectsList) {
      // 禁用
      if (design_type == 2 && !objects.selectable) {
        objects.selectable = false;
      }

      if (objects.type === 'image' && design_type == 2) {

        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true; 
        }

      } else if (objects.type === 'textbox' && design_type == 2) {

        // 设置不可编辑
        objects.editable = false;

        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true; 
        }
      } else {
        // 设置不可编辑
        objects.editable = false;
      }
      
    }

    handAccountCanvas.loadFromJSON(handAccountJson, () => {
      handAccountCanvas.renderAll();
    });
    store.dispatch('design/setItemList', objectsList);
    future = [ ...fut ];
    previous = previous.splice(0, previous.length - 1);
    resolve();
  })
}

/**
 * 下一步
 */
function nextStepOperate() {
  let design_type = store.state.user.queryParams.design_type;
  return new Promise((resolve) => {
    let prev = [ ...previous ], fut = [ ...future ];
    if (fut.length === 0) {
      // prev 只剩最后一值，已到最前
      return Toast({
        message: '已是最后一步',
        position: 'center'
      });
    }

    // prev 出栈，压入 fut
    prev.push(fut.pop());
    // 设置 prev 最后一值为当前画布内容
    handAccountCanvas.clear();
    let handAccountObject = prev[prev.length - 1];
    let handAccountJson = JSON.parse(handAccountObject);
    let objectsList = handAccountJson.objects;
    for (const objects of objectsList) {
      // 禁用
      if (design_type == 2 && !objects.selectable) {
        objects.selectable = false;
      }

      if (objects.type === 'image' && design_type == 2) {

        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true; 
        }

      } else if (objects.type === 'textbox' && design_type == 2) {

        // 设置不可编辑
        objects.editable = false;

        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true; 
        }
      } else {
        // 设置不可编辑
        objects.editable = false;
      }
      
    }
    // future = [ ...fut ];
    handAccountCanvas.loadFromJSON(handAccountJson).renderAll();
    store.dispatch('design/setItemList', objectsList);
    future = future.splice(0, future.length - 1);
    resolve();
  })
}

/**
 * 设置元素激活
 * params 画布参数
 */
async function setFirstItemActive() {
  let objects = handAccountCanvas.getObjects();
  let _index = 0;
  let i = 0;
  for (const item of objects) {
    if (item.selectable) {
      _index = i;
      let actvieItem = objects[_index];
      handAccountCanvas.setActiveObject(actvieItem);
      handAccountCanvas.renderAll();
      return;
    }
    i += 1;
  }
}
async function setItemActive() {
  let objects = handAccountCanvas.getObjects();
  let _index = 0;
  let i = 0;
  for (const item of objects) {
    if (item.type == 'textbox'&&!item.textDirection) {
      _index = i;
      let actvieItem = objects[_index];
      handAccountCanvas.setActiveObject(actvieItem);
      handAccountCanvas.renderAll();
      return;
    }
    i += 1;
  }
}
async function reloadCanvas() {
  return new Promise(async (resolve, reject) => {
    handAccountCanvas.clear();
    handAccountCanvas.renderAll();
    handAccountCanvas.setViewportTransform([1, 0, 0, 1, 0, 0]);
    
    // 重新加载画布
    canvasContentEl = document.querySelector(`#canvasContentEl`); // 画布容器
    const width = canvasContentEl.offsetWidth; 
    const height = canvasContentEl.offsetHeight;
    handAccountCanvas.setWidth(width);
    handAccountCanvas.setHeight(height);

    resolve();
  })
}

/**
 * 加载画布
 * params 画布参数
 * design_type  类型 1 编辑器 2 用户端
 * pic_type 图片类型 2 谐音
 */
async function canvasLoadJson(params, design_type, pic_type) {
  return new Promise(async (resolve, reject) => {
    let backgroundImage = params.backgroundImage;
    let objectsList = params.objects;
    let carText= localStorage.getItem('carText');

    for (const objects of objectsList) {
      // 禁用
      if (design_type == 2 && !objects.selectable) {
        objects.selectable = false;
        objects.evented = false;
      } else {
        objects.selectable = true;
        objects.evented = true;
      }

      if (objects.type === 'image') {

        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true; 
        }

      } else if (objects.type === 'textbox') {

        // 设置不可编辑
        objects.editable = false;

        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true;
        }

        // 字体加载
        if (objects.fontFamilySrc) {
          await downLoadFont({
            name: objects.fontFamily,
            url: objects.fontFamilySrc
          })
        }
      } else if (objects.type === 'group') {
        // 不可以移动
        if (objects.isMove) {
          objects.lockMovementX = true;
          objects.lockMovementY = true; 
        }

        for (const element of objects.objects) {
          if (element.fontFamilySrc) {
            await downLoadFont({
              name: element.fontFamily,
              url: element.fontFamilySrc
            });
          }

          if (element.elType === 'car-model-text' && carText) {
            element.text = carText;
          }
        }
      }
      
    }
    getCanvasSize({
      uri: backgroundImage.src
    }).then(async result => {
      viewWc = parseFloat(result.width / (backgroundImage.width * backgroundImage.scaleX)).toFixed(2);
      setUserZoomAuto(viewWc, backgroundImage.width * backgroundImage.scaleX, backgroundImage.height * backgroundImage.scaleY);
      handAccountCanvas.loadFromJSON(params, () => {
        resolve();
      });
    })
  })
}

// 自动zoom缩放
function setSysZoomAuto(scale, width, height) {
  const center = handAccountCanvas.getCenter();
  const workspace = new fabric.Rect({
    fill: '#000', // transparent
    width,
    height,
    id: 'workspace',
    selectable: false
  });

  handAccountCanvas.setViewportTransform([1, 0, 0, 1, (canvasContentEl.offsetWidth - width) / 2, (canvasContentEl.offsetHeight - height) / 2]);
  handAccountCanvas.zoomToPoint(
    new fabric.Point(center.left, center.top),
    scale,
  );
  handAccountCanvas.centerObject(workspace);
  handAccountCanvas.setWidth(canvasContentEl.offsetWidth);
  handAccountCanvas.setHeight(canvasContentEl.offsetHeight);
  // handAccountCanvas.add(workspace);
  // handAccountCanvas.add(workspace);
  handAccountCanvas.renderAll();
  // 超出画布不展示
  workspace.clone((cloned) => {
    handAccountCanvas.clipPath = cloned;
    handAccountCanvas.requestRenderAll();
  });
  loadRectFalg = true;
  // if (cb) cb(this.workspace.left, this.workspace.top);
}

// 自动zoom缩放
async function setUserZoomAuto(scale, width, height) {
  const center = handAccountCanvas.getCenter();
  const workspace = new fabric.Rect({
    fill: '#fff',
    width: width * scale,
    height: height * scale,
    id: 'workspace',
    selectable: false,
  });

  handAccountCanvas.setViewportTransform([1, 0, 0, 1, (canvasContentEl.offsetWidth - width) / 2, (canvasContentEl.offsetHeight - height) / 2]);
  handAccountCanvas.zoomToPoint(
    new fabric.Point(center.left, center.top),
    scale,
  );
  handAccountCanvas.centerObject(workspace);
  handAccountCanvas.setWidth(canvasContentEl.offsetWidth);
  handAccountCanvas.setHeight(canvasContentEl.offsetHeight);
  // handAccountCanvas.add(workspace);
  await handAccountCanvas.renderAll();
  // 超出画布不展示
  workspace.clone((cloned) => {
    handAccountCanvas.clipPath = cloned;
    handAccountCanvas.requestRenderAll();
  });
  loadRectFalg = true;
  // if (cb) cb(this.workspace.left, this.workspace.top);
}

/**
 * h5上传图片
 * @param {*} files 文件对象
 * @returns data
 */
function h5Upload(files) {
  return new Promise(async (resolve, reject) => {
    Toast.loading({
      message: '上传中',
      position: 'center',
      forbidClick: true,
      duration: 0
    });

    // aliyun oss
    if (cosConfig) {
      const formData = new FormData();
      let key = `${cosConfig.dir}/${new Date().getTime()}-${files.file.name}`;
      key = key.replace(/\s/g, '');
      key = key.replace('+', '');
      formData.append('key', key);
      formData.append('OSSAccessKeyId', cosConfig.accessId);
      formData.append('policy', cosConfig.policy);
      formData.append('signature', cosConfig.signature);
      formData.append('success_action_status', '200');
      formData.append('file', files.file);
      const res = await Axios.post(cosConfig.host, formData);
      if(res.status === 200) {
        resolve({
          cover_path: `${cosConfig.host}/${key}`
        });
      }
      Toast.clear();
    } else {
      // qiniuyun
      // 转换成接口需要的格式
      const formData = new FormData();
      formData.append('file', files.file);
      formData.append('businessId', store.state.user.business_id);
      
      Axios.post(config.baseApi + '/common/upload/templateImage', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
          businessId: store.state.user.business_id
        }
      }).then(imgRes => {
        Toast.clear();
        let result = imgRes.data;
        if (result.code == 200 && result.data) {
          resolve(result.data);
        }
      }).catch(error => {
        Toast.clear();
        resolve(error);
      })
    }
  })
}

/**
 * 头条上传图片
 * @returns data
 */
function toutiaoUpload() {
  let that = this;
  return new Promise((resolve, reject) => {

    // aliyun oss
    if (cosConfig) {
      // 头条上传
      tt.miniProgram.chooseImage({
        count: 1,
        sourceType: 'album',
        success(res) {
          Toast.loading({
            message: '上传中',
            position: 'center',
            forbidClick: true,
            duration: 0
          });
          const filePath = res.tempFilePaths[0];
          const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);
          const key = `${cosConfig.dir}/${new Date().getTime()}-${fileName}`;
          tt.miniProgram.uploadFile({
            url: cosConfig.uploadHost || cosConfig.host,
            filePath,
            name: 'file',
            formData: {
              key,
              policy: cosConfig.policy,
              OSSAccessKeyId: cosConfig.accessId,
              signature: cosConfig.signature
            },
            // header: {
            //   businessId: store.state.user.business_id
            // },
            success(res) {
              Toast.clear();
              if (res.statusCode === 204) {
                resolve({
                  cover_path: `${cosConfig.host}/${key}`
                });
              }
            },
            fail(res) {
              Toast.clear();
            }
          })
        },
        fail(res) {
          console.log('chooseImage fail:', res);
        }
      });
    } else {
      // 头条上传
      tt.miniProgram.chooseImage({
        count: 1,
        sourceType: 'album',
        success(res) {
          Toast.loading({
            message: '上传中',
            position: 'center',
            forbidClick: true,
            duration: 0
          });
          tt.miniProgram.uploadFile({
            url: config.baseApi + '/common/upload/templateImage',
            filePath: res.tempFilePaths[0],
            name: 'file',
            header: {
              businessId: store.state.user.business_id
            },
            success(imgRes) {
              Toast.clear();
              let result = JSON.parse(imgRes.data);
              if (result.code == 200 && result.data) {
                resolve(result.data);
              }
            },
            fail(res) {
              Toast.clear();
            }
          })
        },
        fail(res) {
          console.log('chooseImage fail:', res);
        }
      });
    }
  })
}

/**
 * 图片检测
 * @param {*} src 图片链接
 * @param {*} matting 是否需要抠图
 * @returns 
 */
function censorImage(src) {
  let activeObj = handAccountCanvas.getActiveObject();
  return new Promise((resolve, reject) => {
    Toast.loading({
      message: '检测中',
      position: 'center',
      forbidClick: true,
      duration: 0
    });
    checkCensorImage({
      src,
      is_user: 0
    }).then(safeRes => {
      if (safeRes.code === 200 && safeRes.data) {
        // 检查成功
        Toast.clear();
        if (activeObj.isMatting) {
          let data = imageHumanSegment(src);
          resolve(data);
        } else {
          resolve({
            url: src
          });
        }
      } else {
        Toast.clear();
      }
    });
  })
}

/**
 * 抠图
 * @param {*} src 图片链接
 * @returns 
 */
function imageHumanSegment(src) {
  return new Promise((resolve, reject) => {
    Toast.loading({
      message: '抠图中',
      position: 'center',
      forbidClick: true,
      duration: 0
    });
    humanSegment({
      url: src,
      isAliyun: cosConfig ? '1' : '0',
      RspImgType: 'base64'
    }).then(result => {
      if (result && result.data) {
        Toast.clear();
        resolve(result.data);
      } else {
        Toast.clear();
      }
    }).catch((error) => {
      Toast.clear();
    })
  })
}

// 点击换图
function handleChangeImage() {
  const originTyep = store.state.user.origin;
  let activeObj = handAccountCanvas.getActiveObject();
  if (activeObj.isSticker) {
    store.dispatch('design/setCurrentChangeType', 'changeSticker');
  } else if (originTyep === 'h5' || originTyep === 'kuaishou' || originTyep === 'weixin') {
    store.dispatch('design/setCurrentChangeType', 'changeImage');
    const h5Upload = document.getElementById('h5Upload');
    h5Upload.click();
  } else if (originTyep === 'toutiao') {
    store.dispatch('design/setCurrentChangeType', 'changeImage');
    toutiaoUpload().then(result => {
      let image = result.cover_path;
      // 检测图片
      censorImage(image).then(result_ => {
        updatedImageItem({
          type: 'src',
          uri: result_.url
        }).then(imageResult => {
          if (imageResult && imageResult.width > 200) {
            updatedImageItem({
              type: 'width'
            })
          }
          const canvasJson = handAccountCanvas.toJSON(toJsonAttr);
          store.dispatch('design/setItemList', canvasJson.objects);
        })
      })
    })
  }
}

export default {
  getAliyunCosSignatureFn,
  initCanvas,
  setCanvasBackground,
  addImage,
  discardActiveObject,
  setActiveObjectOpacity,
  addText,
  updateTextBox,
  downLoadFont,
  prevStepOperate,
  nextStepOperate,
  itemSendBackwards,
  itemBringToFront,
  itemSendToBack,
  itemBringForward,
  updatedItem,
  getObject,
  getObjects,
  canvasLoadJson,
  getViewWc,
  h5Upload,
  imageHumanSegment,
  toutiaoUpload,
  censorImage,
  updatedImageItem,
  handleChangeImage,
  setBackgroundImage,
  setFirstItemActive,
  changeSurnameXieYie,
  changeSticker,
  changeCarSticker,
  reloadCanvas,
  addGroup,
  addCarModel,
  addCarModelImage,
  changeCarText,
  setItemActive
}